package myJs.user

import myJs.Utils._

import myJs.myPkg.jquery._
import myJs.myPkg._
import org.scalajs.dom._
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.raw.{Blob, BlobPropertyBag}
import scalatags.Text.all._
import scalatags.Text.{TypedTag, all}
import shared.Pojo.SnpReadsData
import shared.VarTool
import shared.plotly.Bar
import shared.plotly.Sequence.{Doubles, Strings}
import shared.plotly.element.Anchor.Top
import shared.plotly.element.Color.StringColor
import shared.plotly.element.{Anchor, AxisType, HoverInfo, Marker, Orientation}
import shared.plotly.layout.HoverMode.Closest
import shared.plotly.layout.Ref.{Paper, XRef}
import shared.plotly.layout.{Annotation, Axis, Font, Layout, Margin}

import scala.scalajs.js
import scala.scalajs.js.JSON
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import scala.concurrent.ExecutionContext.Implicits.global
import js.JSConverters._
import myJs.Implicits._
import myJs.tool.Tool

import scala.collection.immutable.SeqMap
import scala.scalajs.js.Dynamic.{global => g}

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("MissionSummary")
object MissionSummary {

  val typeTagEmpty = List[TypedTag[String]]()
  val kind = VarTool.batchMissionStr
  val columnNameMap = SeqMap("id" -> "样品编号", "indexId" -> VarTool.indexStr, "sampleIntro" -> VarTool.sampleIntroStr,
    "gender" -> "性别", "comment" -> VarTool.commentStr, "updateTime" -> "更新时间",
    "kind" -> "类型", "autosomalLociTyped" -> "Autosomal Loci Typed", "yLociTyped" -> "Y Loci Typed",
    "xLociTyped" -> "X Loci Typed", "isnpLociTyped" -> "iSNP Loci Typed", "interlocusBalance" -> "Interlocus Balance",
    "singleSource" -> "Single Source"
  )

  @JSExport("init")
  def init = {
    initTable
    refreshTableView
    missionNameChangeByValue(getMissionId)
  }

  def missionNameChangeByValue(myValue: String) = {
    val missionId = myValue
    val index = layer.load(1, Tool.layerOptions.shade(js.Array("0.1", "#fff")))
    refreshMissionInfo(missionId).zip(
      refreshSampleStatInfo(missionId)
    ).zip(
      refreshPosStatInfo(missionId)
    ).zip(
      refreshTable(missionId)(() =>
        bindEvt
      )
    ).map { x =>
      layer.close(index)
    }
  }

  def bindEvt = {
    $("#table").on("check.bs.table", () => getIds)
    $("#table").on("uncheck.bs.table", () => getIds)
    $("#table").on("check-all.bs.table", () => getIds)
    $("#table").on("uncheck-all.bs.table", () => getIds)
    $("#table").on("page-change.bs.table", () => getIds)
  }

  def getIds = {
    val ids = getIdsValue
    if (ids.isEmpty) {
      $(".idsButton").attr("disabled", true)
    } else {
      $(".idsButton").attr("disabled", false)
    }
  }

  def getIdsValue = {
    val arrays = $("#table").bootstrapTable("getAllSelections").toJArJDS
    arrays.map { x =>
      x("id")
    }
  }

  def refreshTableView = {
    val columnNames = List("indexId", "gender", "kind", "panel", "sampleIntro", "comment", "updateTime") :::
      List("interlocusBalance", "singleSource", "autosomalLociTyped", "yLociTyped", "xLociTyped", "isnpLociTyped")
    val html = columnNames.map { x =>
      val showV = columnNameMap.getOrElse(x, x)
      label(marginRight := 30,
        input(`type` := "checkbox", checked, value := x, onclick := s"Utils.setColumns('${x}')",
          showV)
      )
    }.mkString
    $("#checkbox").html(html)
    columnNames.drop(7).foreach { x =>
      g.$("#table").bootstrapTable("hideColumn", x)
      $(s"input:checkbox[value='${x}']").attr("checked", false)
    }
  }

  def initTable = {
    val tableId = "table"
    val columnNames = List("id", "indexId", "gender", "kind", "panel", "sampleIntro", "comment", "updateTime") :::
      List("interlocusBalance", "singleSource", "autosomalLociTyped", "yLociTyped", "xLociTyped", "isnpLociTyped")
    val columns = columnNames.map { columnName =>
      val title = columnNameMap.getOrElse(columnName, columnName)
      val fmt = SampleManage.tbFmt(columnName)
      ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt)
    }
    val options = TableOptions.columns(columns.toJSArray)
    $(s"#${tableId}").bootstrapTable(options)
  }

  def getMissionId = {
    g.missionId.toString
  }

  def getSelectMissionId = {
    Tool.getInputByName("missionName").`val`().toString
  }

  def refreshTable(missionId: String)(f: () => js.Any = () => ()) = {
    val url = g.jsRoutes.controllers.SampleController.getAllSampleByMissionId().url.toString
    Ajax.get(s"${url}?missionId=${missionId}", headers = Map("Content-Type" -> "application/json"),
      responseType = "application/json").map { xhr =>
      val data = JSON.parse(xhr.responseText).toJsAny
      $("#table").bootstrapTable("load", data)
      f()
    }
  }

  def refreshMissionInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.MissionController.getMissionById().url.toString
    Ajax.get(url = s"${url}?missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDS
      dict.foreach { case (k, v) =>
        $(s"#mission #${k}").text(v.toString)
      }
    }
  }

  def refreshSampleStatInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.MissionController.getSampleStatInfo().url.toString
    Ajax.get(url = s"${url}?missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDS
      dict.foreach { case (k, v) =>
        $(s"#sampleStat #${k}").text(v)
      }
    }
  }

  def refreshPosStatInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.MissionController.getPosSamples().url.toString
    Ajax.get(url = s"${url}?missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDJAn
      val samples = dict("samples").toJArJDS
      val liHtml = samples.zipWithIndex.map { case (sampleDict, i) =>
        val active = if (i == 0) "active" else ""
        val id = sampleDict("id")
        li(`class` := active, a(dataToggle := "tab", ariaExpanded := "true", href := s"#${id}", id))
      }.mkString("&nbsp;")
      $("#tab").html(liHtml)

      val tabContentHtml = samples.zipWithIndex.map { case (sampleDict, i) =>
        val idStr = sampleDict("id")
        val gender = VarTool.genderMap.getOrElse(sampleDict("gender"), sampleDict("gender"))
        val active = if (i == 0) "active in" else ""
        val html1 = div(`class` := "col-md-2", verticalAlign := "middle", textAlign := "center",
          div(`class` := "", height := "122px", lineHeight := "122px", gender)
        )

        val autosomalLociTyped = sampleDict("autosomalLociTyped")
        val sameNum = autosomalLociTyped.split("/")(0).toDouble
        val totalNum = autosomalLociTyped.split("/")(1).toDouble
        val percent = ((sameNum / totalNum) * 100).toInt
        val strDiv = s"${sameNum}/${totalNum}"
        val html2 = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number transactions myPercent", dataPercent := percent, id := s"percent${i}",
              span(percent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), strDiv, br, "Autosomal Loci Typed")
          )
        )

        val yLociTyped = sampleDict("yLociTyped")
        val ySameNum = yLociTyped.split("/")(0).toDouble
        val yTotalNum = yLociTyped.split("/")(1).toDouble
        val snpPercent = ((ySameNum / yTotalNum) * 100).toInt
        val snpDiv = s"${ySameNum}/${yTotalNum}"
        val html3 = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number visits myPercent", dataPercent := snpPercent, id := s"percent${i}",
              span(snpPercent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), snpDiv, br, "Y Loci Typed")
          )
        )

        val xLociTyped = sampleDict("xLociTyped")
        val xSameNum = xLociTyped.split("/")(0).toDouble
        val xTotalNum = xLociTyped.split("/")(1).toDouble
        val xPercent = ((xSameNum / xTotalNum) * 100).toInt
        val xDiv = s"${xSameNum}/${xTotalNum}"
        val xHtml = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number visits myPercent", dataPercent := xPercent, id := s"percent${i}",
              span(xPercent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), xDiv, br, "X Loci Typed")
          )
        )

        val iSnpLociTyped = sampleDict("isnpLociTyped")
        val iSnpSameNum = iSnpLociTyped.split("/")(0).toDouble
        val iSnpTotalNum = iSnpLociTyped.split("/")(1).toDouble
        val iSnpPercent = ((iSnpSameNum / iSnpTotalNum) * 100).toInt
        val iSnpDiv = s"${iSnpSameNum}/${iSnpTotalNum}"
        val iSnpHtml = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number visits myPercent", dataPercent := iSnpPercent, id := s"percent${i}",
              span(iSnpPercent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), iSnpDiv, br, "iSNP Loci Typed")
          )
        )

        val bottomHtml = div(`class` := "margin-bottom-10 visible-sm")
        val html = div(`class` := s"tab-pane fade ${active} ", id := idStr,
          div(`class` := "portlet-body",
            div(`class` := "row",
              div(`class` := "col-sm-1",
                html1
              ),
              div(`class` := "col-sm-11",
                html2, html3, xHtml, iSnpHtml,
              ),
              bottomHtml
            ))
        )
        html
      }.mkString("")
      $("#tabContent").html(tabContentHtml)
      g.Dashboard.initEasyPieCharts()
      $(".myPercent").foreach { y =>
        val percent = $(y).attr("data-percent").toString
        val easyPieChart = $(y).data("easyPieChart").get.toEasyPieChart
        easyPieChart.update(percent)
      }
    }
  }

  def refreshNegStatInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.MissionController.getNegSamples().url.toString
    Ajax.get(url = s"${url}?missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDJAn
      val samples = dict("samples").toJArJDS
      val liHtml = samples.zipWithIndex.map { case (sampleDict, i) =>
        val active = if (i == 0) "active" else ""
        val id = sampleDict("id")
        li(`class` := active, a(dataToggle := "tab", ariaExpanded := "true", href := s"#${id}", id))
      }.mkString("&nbsp;")
      $("#tab").html(liHtml)

      val tabContentHtml = samples.zipWithIndex.map { case (sampleDict, i) =>
        val idStr = sampleDict("id")
        val gender = VarTool.genderMap.getOrElse(sampleDict("gender"), sampleDict("gender"))
        val active = if (i == 0) "active in" else ""
        val html1 = div(`class` := "col-md-4", verticalAlign := "middle", textAlign := "center",
          div(`class` := "", height := "122px", lineHeight := "122px", gender)
        )

        val autosomalLociTyped = sampleDict("autosomalLociTyped")
        val sameNum = autosomalLociTyped.split("/")(0).toDouble
        val totalNum = autosomalLociTyped.split("/")(1).toDouble
        val percent = ((sameNum / totalNum) * 100).toInt
        val strDiv = s"${sameNum}/${totalNum}"
        val html2 = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number transactions myPercent", dataPercent := percent, id := s"percent${i}",
              span(percent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), strDiv, br, "Autosomal Loci Typed")
          )
        )

        val yLociTyped = sampleDict("yLociTyped")
        val ySameNum = yLociTyped.split("/")(0).toDouble
        val yTotalNum = yLociTyped.split("/")(1).toDouble
        val snpPercent = ((ySameNum / yTotalNum) * 100).toInt
        val snpDiv = s"${ySameNum}/${yTotalNum}"
        val html3 = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number visits myPercent", dataPercent := snpPercent, id := s"percent${i}",
              span(snpPercent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), snpDiv, br, "Y Loci Typed")
          )
        )

        val xLociTyped = sampleDict("xLociTyped")
        val xSameNum = xLociTyped.split("/")(0).toDouble
        val xTotalNum = xLociTyped.split("/")(1).toDouble
        val xPercent = ((xSameNum / xTotalNum) * 100).toInt
        val xDiv = s"${xSameNum}/${xTotalNum}"
        val xHtml = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number visits myPercent", dataPercent := xPercent, id := s"percent${i}",
              span(xPercent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), xDiv, br, "X Loci Typed")
          )
        )

        val iSnpLociTyped = sampleDict("isnpLociTyped")
        val iSnpSameNum = iSnpLociTyped.split("/")(0).toDouble
        val iSnpTotalNum = iSnpLociTyped.split("/")(1).toDouble
        val iSnpPercent = ((iSnpSameNum / iSnpTotalNum) * 100).toInt
        val iSnpDiv = s"${iSnpSameNum}/${iSnpTotalNum}"
        val iSnpHtml = div(`class` := "col-md-3",
          div(`class` := "easy-pie-chart",
            div(`class` := "number visits myPercent", dataPercent := iSnpPercent, id := s"percent${i}",
              span(iSnpPercent), "%",
              canvas(height := 75, width := 75)),
            span(`class` := "title", href := "javascript:;",
              span(), iSnpDiv, br, "iSNP Loci Typed")
          )
        )

        val bottomHtml = div(`class` := "margin-bottom-10 visible-sm")
        val html = div(`class` := s"tab-pane fade ${active} ", id := idStr,
          div(`class` := "portlet-body",
            div(`class` := "row",
              div(`class` := "col-sm-1",
                html1
              ),
              div(`class` := "col-sm-11",
                html2, html3, xHtml, iSnpHtml,
              ),
              bottomHtml
            ))
        )
        html
      }.mkString("")

      $("#tabContent").html(tabContentHtml)
      g.Dashboard.initEasyPieCharts()
      $(".myPercent").foreach { y =>
        val percent = $(y).attr("data-percent").toString
        val easyPieChart = $(y).data("easyPieChart").get.toEasyPieChart
        easyPieChart.update(percent)
      }
    }
  }

  @JSExport("tabClick")
  def tabClick(y: Element) = {
    val missionId = getMissionId
    $(".myTab").removeClass("mySelected")
    $(y).addClass("mySelected")
    val kind = $(y).find(".widget-thumb-subtitle").attr("data-value").get
    kind match {
      case "阳性" => refreshPosStatInfo(missionId)
      case "阴性" => refreshNegStatInfo(missionId)
    }
  }

  @JSExport("exports")
  def exports = {
    val ids = getIdsValue
    val data = js.Dictionary(
      "ids" -> ids.toJSArray
    )
    val url = g.jsRoutes.controllers.SampleController.exportReports().url.toString
    val layerOptions = LayerOptions.title("正在导出报告").closeBtn(0).skin("layui-layer-molv").btn(js.Array())
    val index = layer.alert(Tool.myElement, layerOptions)
    Ajax.post(url = s"${url}", data = JSON.stringify(data),
      headers = Map("Content-Type" -> "application/json"), responseType = "blob").map { xhr =>
      layer.close(index)
      Tool.downloadZip("reports.zip", xhr.response)
    }
  }


}
